package cn.stylefeng.guns.modular.system.controller.webController;

import cn.hutool.core.bean.BeanUtil;
import cn.stylefeng.guns.core.common.annotion.BussinessLog;
import cn.stylefeng.guns.core.common.annotion.Permission;
import cn.stylefeng.guns.core.common.constant.dictmap.DeptDict;
import cn.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import cn.stylefeng.guns.core.log.LogObjectHolder;
import cn.stylefeng.guns.core.shiro.ShiroKit;
import cn.stylefeng.guns.core.util.StringUtil;
import cn.stylefeng.guns.core.util.TencentCloudUtils;
import cn.stylefeng.guns.modular.system.entity.*;
import cn.stylefeng.guns.modular.system.model.SchoolDto;
import cn.stylefeng.guns.modular.system.model.StudentDto;
import cn.stylefeng.guns.modular.system.service.*;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.RequestEmptyException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;

/**
 * ClassName:    ApiController
 * Package:    cn.stylefeng.guns.modular.system.controller.webController
 * Description:
 * Datetime:    2020/8/7   12:20
 */
@Api(value = "人员管理接口", tags = "ApiController", description = "人员管理接口")
@AllArgsConstructor
@RestController
@RequestMapping("/api/user/")
public class ApiController extends BaseController {

    final private String PASSPORTPHOTO = "user/";
    private SchoolCodeService schoolCodeService;
    private StudentCodeService studentCodeService;
    private SysSchoolService schoolService;
    private SysStudentService studentService;
    private SysAgentService sysAgentService;
    private SysSchoolAgentService sysSchoolAgentService;
    private UserService userService;
    private RoleService roleService;
    private DeptService deptService;

    @ApiOperation(value = "获取用户信息", notes="获取用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", paramType = "query"),
            @ApiImplicitParam(name = "phoneNumber", value = "手机号码", paramType = "query"),
    })
    @RequestMapping(value = "/getUser",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getUser (@RequestParam(value = "userId",required = false) Long userId,
                                 @RequestParam(value = "phoneNumber",required = false) String phoneNumber){
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .select("user_id", "avatar", "account", "name", "birthday", "sex", "email", "phone", "user_percentage", "role_id", "dept_id")
                .ne("status", "DELETED");
        if(ToolUtil.isNotEmpty(userId)){
            wrapper.eq("user_id", userId);
        }
        if(ToolUtil.isNotEmpty(phoneNumber)){
            wrapper.eq("account", phoneNumber);
        }
        Map<String, Object> map = userService.getMap(wrapper);
       if(ToolUtil.isNotEmpty(map)){
           Role role = roleService.getById(map.get("role_id").toString());
           if(role.getName().equals("学校")){
               map.put("school",schoolService.getSysSchool(Long.parseLong(map.get("user_id").toString())));
           }else if(role.getName().equals("学生")){
               map.put("student",studentService.getStudent(Long.parseLong(map.get("user_id").toString())));
           }else if(role.getName().equals("代理人")){
               map.put("agent",sysAgentService.getSysAgent(Long.parseLong(map.get("user_id").toString())));
           }
       }
        return ResponseData.success(map);
    }

    @ApiOperation(value = "获取用户角色", notes="获取用户角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", paramType = "query",required = true),
    })
    @RequestMapping(value = "/getRole",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getRole (@RequestParam(value = "roleId") Long roleId){
        return ResponseData.success(roleService.getById(roleId));
    }

    @ApiOperation(value = "获取用户部门", notes="获取用户部门")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "query",required = true),
    })
    @RequestMapping(value = "/getDept",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getDept (@RequestParam(value = "deptId") Long deptId){
        return ResponseData.success(deptService.getById(deptId));
    }

    @ApiOperation(value = "获取部门树", notes="获取部门树")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "createUser", value = "创建人ID", paramType = "query",required = true),
            @ApiImplicitParam(name = "pId", value = "部门父ID", paramType = "query"),
    })
    @RequestMapping(value = "/getDeptTree",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getDeptTree (@RequestParam(value = "createUser") Long createUser,
                                     @RequestParam(value = "pId",defaultValue = "0") Long pId){
        return ResponseData.success(deptService.list(new QueryWrapper<Dept>()
                .eq("pid",pId).eq("create_user",createUser).eq("effective",1)));
    }

    @ApiOperation(value = "添加部门", notes="添加部门")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "query"),
            @ApiImplicitParam(name = "pid", value = "部门父ID", paramType = "query",required = true),
            @ApiImplicitParam(name = "simpleName", value = "简称", paramType = "query",required = true),
            @ApiImplicitParam(name = "fullName", value = "全称", paramType = "query",required = true),
            @ApiImplicitParam(name = "sort", value = "排序", paramType = "query",required = true),
            @ApiImplicitParam(name = "createUser", value = "创建人ID", paramType = "query",required = true),
    })
    @RequestMapping(value = "/deptSave",method = RequestMethod.POST, produces = "application/json")
    public ResponseData deptSave (Dept dept){
        return ResponseData.success(deptService.addDept(dept));
    }

    @ApiOperation(value = "删除部门", notes="删除部门")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "query",required = true),
    })
    @RequestMapping(value = "/deptDelete",method = RequestMethod.POST, produces = "application/json")
    public ResponseData deptDelete(@RequestParam Long deptId) {
        deptService.deleteDept(deptId);
        return SUCCESS_TIP;
    }

    @ApiOperation(value = "获取学校代码", notes="获取学校代码")
    @RequestMapping(value = "/getSchoolCode",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getSchoolCode (){
        return ResponseData.success(schoolCodeService.getSchoolCode());
    }

    @ApiOperation(value = "获取考生号", notes="获取考生号")
    @RequestMapping(value = "/getStudentCode",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getStudentCode (){
        return ResponseData.success(studentCodeService.getStudentCode());
    }


    @ApiOperation(value = "通过学校代码获取学校信息", notes="通过学校代码获取学校信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "学校代码", paramType = "query",required = true),
    })
    @RequestMapping(value = "/getSchoolByCode",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getSchoolByCode (@RequestParam(value = "code") String code){
        return ResponseData.success(schoolService.getOne(new QueryWrapper<SysSchool>().eq("school_code", code)));
    }

    @ApiOperation(value = "通过考生号获取学生信息", notes="通过考生号获取学生信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "考生号", paramType = "query",required = true),
    })
    @RequestMapping(value = "/getStudentByCode",method = RequestMethod.POST, produces = "application/json")
    public ResponseData getStudentByCode (@RequestParam(value = "code") String code){
        return ResponseData.success(studentService.getOne(new QueryWrapper<SysStudent>().eq("student_code", code)));
    }

    @ApiOperation(value = "机构注册", notes="机构注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId", paramType = "query"),
            @ApiImplicitParam(name = "schoolId", value = "schoolId", paramType = "query"),
            @ApiImplicitParam(name = "schoolName", value = "学校名称", paramType = "query",required = true),
            @ApiImplicitParam(name = "schoolCode", value = "学校代码", paramType = "query",required = true),
            @ApiImplicitParam(name = "schoolProvince", value = "省", paramType = "query",required = true),
            @ApiImplicitParam(name = "schoolCity", value = "市", paramType = "query",required = true),
            @ApiImplicitParam(name = "schoolCounty", value = "区县", paramType = "query",required = true),
            @ApiImplicitParam(name = "schoolAddress", value = "详细地址", paramType = "query",required = true),
            @ApiImplicitParam(name = "account", value = "手机号码", paramType = "query",required = true),
            @ApiImplicitParam(name = "password", value = "密码", paramType = "query",required = true),
            @ApiImplicitParam(name = "name", value = "负责人", paramType = "query",required = true),
            @ApiImplicitParam(name = "email", value = "QQ邮箱", paramType = "query",required = true),
            @ApiImplicitParam(name = "signUpNum", value = "报名人数", paramType = "query",required = true),
    })
    @Transactional
    @RequestMapping(value = "/schoolSave",method = RequestMethod.POST, produces = "application/json")
    public ResponseData schoolSave (SchoolDto schoolDto){
        schoolService.schoolSave(schoolDto);
        return SUCCESS_TIP;
    }

    @ApiOperation(value = "学生注册", notes="学生注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId", paramType = "query"),
            @ApiImplicitParam(name = "studentId", value = "studentId", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "姓名", paramType = "query",required = true),
            @ApiImplicitParam(name = "sex", value = "性别", paramType = "query",required = true),
            @ApiImplicitParam(name = "createUser", value = "学校userId", paramType = "query",required = true),
            @ApiImplicitParam(name = "deptId", value = "班级ID", paramType = "query",required = true),
            @ApiImplicitParam(name = "studentCode", value = "考生号", paramType = "query",required = true),
            @ApiImplicitParam(name = "account", value = "手机号码", paramType = "query",required = true),
            @ApiImplicitParam(name = "password", value = "密码", paramType = "query",required = true),
            @ApiImplicitParam(name = "passportPhoto", value = "证件照", paramType = "query")
    })
    @Transactional
    @RequestMapping(value = "/studentSave",method = RequestMethod.POST, produces = "application/json")
    public ResponseData studentSave (StudentDto studentDto){
        studentService.studentSave(studentDto);
        return SUCCESS_TIP;
    }

    @ApiOperation(value = "学生编辑", notes="学生编辑")
    @RequestMapping(value = "/studentEtid",method = RequestMethod.POST, produces = "application/json")
    public ResponseData studentEtid (SysStudent student){
        if(ToolUtil.isNotEmpty(student.getPassportPhoto())){
            String cover = PASSPORTPHOTO + StringUtil.getFileName(student.getPassportPhoto());
            TencentCloudUtils.copyObject(student.getPassportPhoto(), cover);
            student.setPassportPhoto(cover);
        }
        studentService.updateById(student);
        return SUCCESS_TIP;
    }


    @ApiOperation(value = "账号密码登录", notes="账号密码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "账号", paramType = "query",required = true),
            @ApiImplicitParam(name = "password", value = "密码", paramType = "query",required = true),
    })
    @RequestMapping(value = "/userLogin",method = RequestMethod.POST, produces = "application/json")
    public ResponseData userLogin(@RequestParam("username") String username,
                                  @RequestParam("password") String password) {
        User user = userService.getOne(new QueryWrapper<User>()
                .eq("account", username).eq("status","ENABLE").eq("examine",1));
        if (user == null) {
            return ResponseData.error("账号错误!");
        }
        if(!user.getPassword().equals(ShiroKit.md5(password, user.getSalt()))){
            return ResponseData.error("密码错误!");
        }
        return ResponseData.success(user);
    }

    @ApiOperation(value = "手机号码验证码登录", notes="手机号码验证码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phoneNumber", value = "手机号码", paramType = "query",required = true)
    })
    @RequestMapping(value = "/phoneLogin",method = RequestMethod.POST, produces = "application/json")
    public ResponseData phoneLogin(@RequestParam("phoneNumber") String phoneNumber) {
        User user = userService.getByAccount(phoneNumber);
        return Optional.ofNullable(user).map(u-> (ResponseData) ResponseData.success(u))
                .orElseGet(()-> ResponseData.error("数据错误！") );
    }

    @ApiOperation(value = "忘记密码", notes="忘记密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phoneNumber", value = "手机号码", paramType = "query",required = true),
            @ApiImplicitParam(name = "password", value = "密码", paramType = "query",required = true),
    })
    @RequestMapping(value = "/forgetPassword",method = RequestMethod.POST, produces = "application/json")
    public ResponseData forgetPassword (@RequestParam(value = "phoneNumber") String phoneNumber,
                                        @RequestParam(value = "password") String password){
        User user = userService.getByAccount(phoneNumber);
        return Optional.ofNullable(user).map(u->{
            u.setPassword(ShiroKit.md5(password, user.getSalt()));
            userService.updateById(u);
            return (ResponseData) SUCCESS_TIP;
        }).orElseGet(()->{
            return  ResponseData.error("数据错误！");
        });
    }
    /**
     * 修改用户的密码
     *
     */
    @ApiOperation(value = "修改用户的密码", notes="修改用户的密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", paramType = "query",required = true),
            @ApiImplicitParam(name = "oldPassword", value = "原始密码", paramType = "query",required = true),
            @ApiImplicitParam(name = "newPassword", value = "新密码", paramType = "query",required = true),
    })
    @RequestMapping(value = "/changePwd",method = RequestMethod.POST, produces = "application/json")
    public Object changePwd(@RequestParam("userId") Long userId,
                            @RequestParam("oldPassword") String oldPassword,
                            @RequestParam("newPassword") String newPassword) {
        this.userService.changePwd(userId, oldPassword, newPassword);
        return SUCCESS_TIP;
    }

    @ApiOperation(value = "用户列表", notes="用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", paramType = "query"),
            @ApiImplicitParam(name = "createUser", value = "创建人ID", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "姓名", paramType = "query")
    })
    @RequestMapping(value = "/userList",method = RequestMethod.POST, produces = "application/json")
    public ResponseData userList (@RequestParam(value = "roleId",required = false) Long roleId,
                                  @RequestParam(value = "createUser",required = false) Long createUser,
                                  @RequestParam(value = "name",required = false) String name){
        return ResponseData.success(userService.userList(roleId,createUser,name));
    }

    @ApiOperation(value = "学校关联的代理人数据", notes="学校关联的代理人数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId", paramType = "query",required = true),
    })
    @RequestMapping(value = "/relationUser",method = RequestMethod.POST, produces = "application/json")
    public ResponseData relationUser (@RequestParam("userId") Long userId){
        Map<String, Object> school_user_id = sysSchoolAgentService.getMap(new QueryWrapper<SysSchoolAgent>()
                .select("GROUP_CONCAT(agent_user_id) agentIds")
                .eq("school_user_id", userId));
        return Optional.ofNullable(school_user_id).map(map -> {
            return (ResponseData) ResponseData.success(map.get("agentIds").toString());
        }).orElseGet(()->{
            return ResponseData.error("数据错误！");
        });

    }


}
